package org.example.erpapiservicespringpgimpl;

import org.example.erpapicommon.Util.BasePage;
import org.example.erpapicommon.Util.Pageable;
import org.example.erpapicommon.Util.Param.ProductQueryParam;
import org.example.erpapicommon.model.Product;
import org.example.erpapicommon.model.SimpleCategory;
import org.example.erpapicommon.model.SimpleSupplier;
import org.example.erpapicommon.model.TProduct;
import org.example.erpapicommon.service.OtherService;
import org.example.erpapicommon.service.ProductService;
import org.example.erpapiservicespringpgimpl.Dao.ProductDao;
import org.example.erpapiservicespringpgimpl.entity.ProductEntity;
import org.example.erpapiservicespringpgimpl.mapper.ProductMapper;

import org.example.erpapiservicespringpgimpl.mapper.ProductPageMapper;
import org.seasar.doma.jdbc.SelectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

@Component
public class ProductServicePgImpl implements ProductService {
    @Autowired
    private ProductDao productDao;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OtherService otherService;
    @Autowired
    private ProductPageMapper productPageMapper;
    @Override
    @Cacheable(value="erp_api", key = "'product_'+#id")
    public Optional<Product> getProductById(Integer id) {
        Optional<ProductEntity> productOptional = productDao.findById(id);
        if (productOptional.isEmpty()) {
            return Optional.empty();
        }
        List<SimpleCategory> categoryList=otherService.findSimpleCategoriesById(productOptional.get().getCategoryId());
        List<SimpleSupplier> supplierList=otherService.findSimpleSuppliersByProductsId(id);
        return productOptional.map(productEntity -> {
            Product product = productMapper.fromEntity(productEntity);
            product.setCategory(categoryList);
            product.setSuppliers(supplierList);
            return product;
        });
    }

    @Override
    @Cacheable(value = "erp_api",key = "'pageProducts_'+ #param.hashCode()", condition = "#param != null")
    public Pageable<TProduct> PageProducts(ProductQueryParam param) {
        SelectOptions options = SelectOptions.get().count();
        List<ProductEntity> productList = productDao.PageProducts(param, options);
        int totalCount = (int)options.getCount();
        int pageNumber = param.getPageNumber();
        int pageSize = param.getPageSize();
        int totalPage = PageUtil.getTotalPage((int) totalCount, pageSize);
        int offset = PageUtil.getOffset(pageNumber, pageSize);
        options.offset(offset).limit(pageSize);
        List<ProductEntity> productEntityList1 = productDao.PageProducts(param, options);
        List<TProduct> TProductList =productPageMapper.fromEntityList(productEntityList1);
        Pageable<TProduct> TProductPageable = new BasePage<>(TProductList, pageNumber, pageSize, totalPage,totalCount );
        return TProductPageable;
    }


    @Override
    @Cacheable(value = "erp_api",key = "'pageProducts_'+ #param.hashCode()+'bySupplier_'+#supplierId", condition = "#param != null")
    public Pageable<TProduct> PageProductsbySupplierId(ProductQueryParam param, Integer supplierId) {
        SelectOptions options = SelectOptions.get().count();
        List<ProductEntity> productList = productDao.PageProductsbySupplierId(param, supplierId,options);
        int totalCount = (int)options.getCount();
        int pageNumber = param.getPageNumber();
        int pageSize = param.getPageSize();
        int totalPage = PageUtil.getTotalPage((int) totalCount, pageSize);
        int offset = PageUtil.getOffset(pageNumber, pageSize);
        options.offset(offset).limit(pageSize);
        List<ProductEntity> productEntityList1 = productDao.PageProductsbySupplierId(param, supplierId,options);
        List<TProduct> TProductList =productPageMapper.fromEntityList(productEntityList1);
        Pageable<TProduct> TProductPageable = new BasePage<>(TProductList, pageNumber,  pageSize,totalPage,totalCount );
        return TProductPageable;
    }
}
